package com.group01.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.query.MPJLambdaQueryWrapper;
import com.group01.dto.Category.CategoryInsertInfoDTO;
import com.group01.dto.Category.CategoryUpdateInfoDTO;
import com.group01.enums.CodeAndMessageEnum;
import com.group01.pojo.Category;
import com.group01.result.CategoryPageTemplate;

import com.group01.result.Result;
import com.group01.service.CategoryService;
import com.group01.mapper.CategoryMapper;
import com.group01.utils.BeanCopyUtils;
import com.group01.vo.Category.CategoryGetPageVO;
import com.group01.vo.Category.CategoryInfoVO;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 19559
* @description 针对表【es_category(分类表)】的数据库操作Service实现
* @createDate 2024-06-21 15:33:03
*/
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService{

    /**
     * 注入CategoryMapper
     */
    private final CategoryMapper categoryMapper;

    public CategoryServiceImpl(CategoryMapper categoryMapper) {
        this.categoryMapper = categoryMapper;
    }

    /**
     * 分页 + 条件查询分类信息
     * @param name 分类名称
     * @param pageNum 当前页码
     * @param pageSize 每页记录数
     * @return {@link Result }<{@link CategoryPageTemplate }>
     */
    @Override
    public Result<CategoryPageTemplate> getCategoryPageTree(String name, Integer pageNum, Integer pageSize) {
        MPJLambdaQueryWrapper<Category> queryWrapper = new MPJLambdaQueryWrapper<>();
        queryWrapper.selectAll(Category.class); // 选择所有分类列
        if(StringUtils.hasText(name)) {
            queryWrapper
                    .like(Category::getName, name) // 模糊匹配分类名
                    .or(wrapper ->
                            wrapper.inSql(Category::getId, "select parent_id from es_category where name like '%" + name + "%'")
                    )
                    .or(wrapper ->
                            wrapper.inSql(Category::getParentId, "select id from es_category where name like '%" + name + "%'")
                    );
        }

        Page<Category> page = new Page<>(pageNum, pageSize);
        categoryMapper.selectPage(page, queryWrapper);

        // Bean拷贝
        List<CategoryGetPageVO> categoryGetPageVOList = BeanCopyUtils.copyBeanList(page.getRecords(), CategoryGetPageVO.class);
        // 构造树
        List<CategoryGetPageVO> vos = CategoryGetPageVO.buildCategoryTree(categoryGetPageVOList);
        return Result.success(CodeAndMessageEnum.FIND_RESULT, new CategoryPageTemplate(page.getTotal(), vos));
    }

    /**
     * 查询全部分类（阉割版 分页 + 条件查询分类信息）
     * @return {@link Result }<{@link List }<{@link CategoryGetPageVO }>>
     */
    @Override
    public Result<List<CategoryGetPageVO>> getAllCategory() {
        List<Category> categoryList = categoryMapper.selectList(null);

        // Bean拷贝
        List<CategoryGetPageVO> categoryGetPageVOList = BeanCopyUtils.copyBeanList(categoryList, CategoryGetPageVO.class);
        // 构造树
        List<CategoryGetPageVO> vos = CategoryGetPageVO.buildCategoryTree(categoryGetPageVOList);
        return Result.success(CodeAndMessageEnum.FIND_RESULT, vos);
    }

    /**
     * 根据分类ID查询分类信息
     * @param id 分类ID
     * @return {@link Result }<{@link CategoryInfoVO }>
     */
    @Override
    public Result<CategoryInfoVO> getCategoryById(Integer id) {
        Category category = categoryMapper.selectById(id);
        if(category == null) {
            return Result.error(CodeAndMessageEnum.FIND_CATEGORY_ID_FAIL, null);
        }
        CategoryInfoVO categoryInfoVO = BeanCopyUtils.copyBean(category, CategoryInfoVO.class);

        return Result.success(CodeAndMessageEnum.FIND_RESULT, categoryInfoVO);
    }

    /**
     * 新增分类
     * @param categoryInsertInfoDTO 分类信息传输对象DTO
     * @return {@link Result }<{@link String }>
     */
    @Override
    public Result<String> addCategory(CategoryInsertInfoDTO categoryInsertInfoDTO) {
        // 分类名校验
        Long count = categoryMapper.selectCount(new LambdaQueryWrapper<Category>().eq(Category::getName, categoryInsertInfoDTO.getName()));
        if(count != 0) {
            return Result.error(CodeAndMessageEnum.FIND_CATEGORY_EXIST);
        }
        if(categoryInsertInfoDTO.getParentId() != null) {
            count = categoryMapper.selectCount(new LambdaQueryWrapper<Category>().eq(Category::getId , categoryInsertInfoDTO.getParentId()));
            if(count == 0) {
                return Result.error(CodeAndMessageEnum.FIND_CATEGORY_PARENT_ID_NULL);
            }
        }
        // Bean拷贝并新增
        categoryMapper.insert(BeanCopyUtils.copyBean(categoryInsertInfoDTO, Category.class));
        return Result.success(CodeAndMessageEnum.INSERT_SUCCESS);
    }

    /**
     * 修改分类信息
     * @param categoryUpdateInfoDTO 分类信息传输对象DTO
     * @return {@link Result }<{@link String }>
     */
    @Override
    public Result<String> updateCategory(CategoryUpdateInfoDTO categoryUpdateInfoDTO) {
        Integer count = categoryMapper.checkCategoryId(categoryUpdateInfoDTO.getId());
        if(count == 0) {
            return Result.error(CodeAndMessageEnum.FIND_CATEGORY_ID_FAIL, null);
        }
        count = categoryMapper.checkCategoryName(categoryUpdateInfoDTO.getName(), categoryUpdateInfoDTO.getId());
        if(count > 0) {
            return Result.error(CodeAndMessageEnum.FIND_CATEGORY_EXIST, null);
        }

        // Bean拷贝
        categoryMapper.updateById(BeanCopyUtils.copyBean(categoryUpdateInfoDTO, Category.class));

        return Result.success(CodeAndMessageEnum.UPDATE_SUCCESS);
    }

    /**
     * 删除 + 批量删除分类信息
     * @param ids 分类ID集合
     * @return {@link Result }<{@link String }>
     */
    @Override
    public Result<String> deleteCategoryByIds(String ids) {
        List<Integer> idList = Arrays.stream(ids.split(","))
                .map(Integer::parseInt)
                .collect(Collectors.toList());
        categoryMapper.deleteBatchIds(idList);
        return Result.success(CodeAndMessageEnum.DELETE_SUCCESS);
    }

}




